﻿using Onshi.POS.Modelo.Entidades;
using Onshi.POS.Modelo.Enumeradores;
using Onshi.POS.Repositorios;
using Onshi.POS.Articulos.Vistas;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Onshi.POS.Articulos
{
    public class DescuentosRecargosCantidadesPresentador
    {
        #region Constructores

        public DescuentosRecargosCantidadesPresentador(IDescuentosRecargosCantidades vista)
        {
            this.vista = vista;
        }

        #endregion

        #region Atributos

        private IDescuentosRecargosCantidades vista;
        private List<DescuentoRecargoCantidad> listado;

        #endregion

        #region Propiedades

        private RepositorioEventos RepositorioEventos
        {
            get { return new RepositorioEventos(); }
        }

        private RepositorioDescuentosRecargosCantidades RepositorioDescuentosRecargosCantidades
        {
            get { return new RepositorioDescuentosRecargosCantidades(); }
        }

        private RepositorioUsuarios RepositorioUsuarios
        {
            get { return new RepositorioUsuarios(); }
        }

        private RepositorioRegistros RepositorioRegistros
        {
            get { return new RepositorioRegistros(); }
        }

        private RepositorioPermisos RepositorioPermisos
        {
            get { return new RepositorioPermisos(); }
        }

        private RepositorioArticulos RepositorioArticulos
        {
            get { return new RepositorioArticulos(); }
        }

        #endregion

        #region Metodos

        private void CargarFiltrarLista()
        {
            listado = RepositorioDescuentosRecargosCantidades.DevolverTodos();
            Filtrar();
        }

        public void Inicializar()
        {
            vista.ListadoDescuentosRecargosCantidades = listado = RepositorioDescuentosRecargosCantidades.DevolverTodos();
        }

        public void Eliminar()
        {
            var usuario = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.DescuentosRecargosCantidadesBaja))
                throw new Exception("Permisos insuficientes");

            if (vista.IdDescuentoRecargoCantidad == (Int32)EnumDescuentosRecargosCantidades.SinDescuentoNiRecargo)
                throw new Exception("El descuento y recargo por cantidad no se permite eliminar");

            var descuentoRecargoCantidad = RepositorioDescuentosRecargosCantidades.DevolverPorId(vista.IdDescuentoRecargoCantidad);
            if (descuentoRecargoCantidad == null)
                throw new Exception("El descuento y recargo por cantidad no existe");

            var descuentoRecargoCantidadPredeterminado = RepositorioDescuentosRecargosCantidades.DevolverPorId((Int32)EnumDescuentosRecargosCantidades.SinDescuentoNiRecargo);
            if (descuentoRecargoCantidadPredeterminado == null)
                throw new Exception("El descuento y recargo por cantidad predeterminado no existe");

            var registro = new Registro();
            registro.Usuario = usuario;
            registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.DescuentosRecargosCantidadesBaja);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            RepositorioArticulos.ModificarDescuentoRecargoCantidad(descuentoRecargoCantidadPredeterminado, descuentoRecargoCantidad);
            RepositorioDescuentosRecargosCantidades.EliminarDetallesPorDescuentoRecargoCantidad(descuentoRecargoCantidad);
            RepositorioDescuentosRecargosCantidades.Eliminar(descuentoRecargoCantidad);
            RepositorioRegistros.Insertar(registro);

            CargarFiltrarLista();
        }

        public void Actualizar()
        {
            CargarFiltrarLista();
        }

        public void Filtrar()
        {
            var consulta = (from item in listado
                            where item.Nombre.Trim().ToLower().Contains(vista.NombreFiltro.Trim().ToLower())
                            & item.TieneObservaciones == (vista.ObservacionesFiltro == EnumSiNo.Todos ? item.TieneObservaciones : (vista.ObservacionesFiltro == EnumSiNo.Si ? true : false))
                            select item).ToList();
            vista.ListadoDescuentosRecargosCantidades = consulta;
        }

        public void Aceptar()
        {
            var usuario = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (vista.IdDescuentoRecargoCantidad == 0)
            {
                if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.DescuentosRecargosCantidadesAlta))
                    throw new Exception("Permisos insuficientes");
            }
            else if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.DescuentosRecargosCantidadesModificacion))
                throw new Exception("Permisos insuficientes");

            if (String.IsNullOrWhiteSpace(vista.Nombre))
                throw new Exception("El nombre no puede quedar vacío");
            if (vista.ListadoDetalles.Count == 0)
                throw new Exception("Debe haber al menos una combinación");

            DescuentoRecargoCantidad descuentoRecargoCantidad;
            if (vista.IdDescuentoRecargoCantidad != 0)
            {
                if (vista.IdDescuentoRecargoCantidad == (Int32)EnumDescuentosRecargosCantidades.SinDescuentoNiRecargo)
                    throw new Exception("El descuento y recargo por cantidad no se permite modificar");
                descuentoRecargoCantidad = RepositorioDescuentosRecargosCantidades.DevolverPorId(vista.IdDescuentoRecargoCantidad);
                if (descuentoRecargoCantidad == null)
                    throw new Exception("El descuento y recargo por cantidad no existe");
            }
            else
                descuentoRecargoCantidad = new DescuentoRecargoCantidad();

            descuentoRecargoCantidad.Nombre = vista.Nombre.Trim();
            descuentoRecargoCantidad.Observaciones = vista.Observaciones.Trim();

            var registro = new Registro();
            registro.Usuario = usuario;
            if (vista.IdDescuentoRecargoCantidad == 0)
                registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.DescuentosRecargosCantidadesAlta);
            else
                registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.DescuentosRecargosCantidadesModificacion);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            if (vista.IdDescuentoRecargoCantidad == 0)
                RepositorioDescuentosRecargosCantidades.Insertar(descuentoRecargoCantidad);
            else
            {
                RepositorioDescuentosRecargosCantidades.Modificar(descuentoRecargoCantidad);
                RepositorioDescuentosRecargosCantidades.EliminarDetallesPorDescuentoRecargoCantidad(descuentoRecargoCantidad);
            }
            RepositorioRegistros.Insertar(registro);

            foreach (var item in vista.ListadoDetalles)
                RepositorioDescuentosRecargosCantidades.InsertarDetalle(descuentoRecargoCantidad, item);

            CargarFiltrarLista();
        }

        public void DetalleAgregar()
        {
            if (vista.DetalleCantidad < 0)
                throw new Exception("La cantidad debe ser mayor a cero");
            if (vista.ListadoDetalles.Exists(x => x.Cantidad == vista.DetalleCantidad))
                throw new Exception("Ya existe un descuento o recargo para esa cantidad");

            var contador = 1;
            var detalleNuevo = new DescuentoRecargoCantidadDetalle();
            detalleNuevo.Id = contador;
            detalleNuevo.Cantidad = vista.DetalleCantidad;
            detalleNuevo.DescuentoRecargo = vista.DetalleDescuentoRecargo;

            var listadoNuevo = new List<DescuentoRecargoCantidadDetalle>();
            listadoNuevo.Add(detalleNuevo);
            foreach (var item in vista.ListadoDetalles)
            {
                contador++;
                item.Id = contador;
                listadoNuevo.Add(item);
            }
            vista.ListadoDetalles = listadoNuevo.OrderBy(x => x.Cantidad).ToList();
        }

        public void DetalleQuitar()
        {
            var listadoNuevo = new List<DescuentoRecargoCantidadDetalle>();
            foreach (var item in vista.ListadoDetalles)
                if (item.Id != vista.DetalleId)
                    listadoNuevo.Add(item);
            vista.ListadoDetalles = listadoNuevo.OrderBy(x => x.Cantidad).ToList();
        }

        public void DetalleEditar()
        {
            if (vista.DetalleCantidad < 0)
                throw new Exception("La cantidad debe ser mayor a cero");
            if (vista.ListadoDetalles.Exists(x => x.Cantidad == vista.DetalleCantidad && x.Id != vista.DetalleId))
                throw new Exception("Ya existe un descuento o recargo para esa cantidad");

            var contador = 1;
            var detalleNuevo = new DescuentoRecargoCantidadDetalle();
            detalleNuevo.Id = contador;
            detalleNuevo.Cantidad = vista.DetalleCantidad;
            detalleNuevo.DescuentoRecargo = vista.DetalleDescuentoRecargo;

            var listadoQuitar = new List<DescuentoRecargoCantidadDetalle>();
            foreach (var item in vista.ListadoDetalles)
                if (item.Id != vista.DetalleId)
                    listadoQuitar.Add(item);

            var listadoNuevo = new List<DescuentoRecargoCantidadDetalle>();
            listadoNuevo.Add(detalleNuevo);
            foreach (var item in listadoQuitar)
            {
                contador++;
                item.Id = contador;
                listadoNuevo.Add(item);
            }
            vista.ListadoDetalles = listadoNuevo.OrderBy(x => x.Cantidad).ToList();
        }

        #endregion
    }
}
